package column

import (
	"fmt"
	"game/game-db/orm/metag"
	"reflect"
	"strings"
	"unsafe"
)

type Float32ColumnMeta struct {
	ColumnMeta
	extra []string
}

func (t *Float32ColumnMeta) FillValue(objField reflect.Value, fieldValue reflect.Value) {
	if objField.CanSet() {
		objField.SetFloat(fieldValue.Interface().(float64))
	} else {
		objField = reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		objField.SetFloat(fieldValue.Interface().(float64))
	}
}
func (t *Float32ColumnMeta) TakeValue(objField reflect.Value) interface{} {
	if objField.CanInterface() {
		return objField.Interface()
	} else {
		objField = reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		return objField.Interface()
	}
}

func (t *Float32ColumnMeta) DbColumnType() string {
	if len(t.extra) != 2 {
		return "float(20, 2)"
	} else {
		return fmt.Sprintf("float(%s, %s)", t.extra[0], t.extra[1])
	}
}

func (t *Float32ColumnMeta) DefaultValue() string {
	if t.defaultValue == "" {
		return "DEFAULT 0"
	} else {
		return fmt.Sprintf("DEFAULT %s", t.defaultValue)
	}
}

func (t *Float32ColumnMeta) IsChange(dbColumnType string, dbColumnExtra string) bool {
	if !strings.HasPrefix(dbColumnType, "float") {
		return true
	}
	frontIdx := strings.Index(dbColumnType, "(")
	backIdx := strings.Index(dbColumnType, ")")
	precision := strings.Split(dbColumnType[frontIdx+1:backIdx], ",")
	if len(precision) == 2 {
		precision0 := "20"
		precision1 := "2"
		if len(t.extra) == 2 {
			precision0 = t.extra[0]
			precision1 = t.extra[1]
		}
		if precision0 == strings.TrimSpace(precision[0]) && precision1 == strings.TrimSpace(precision[1]) {
			return false
		} else {
			return true
		}
	} else {
		return true
	}
}

func NewFloat32Field(structField reflect.StructField, columnMetag metag.ColumnMetag) IColumnMeta {
	var meta Float32ColumnMeta
	meta.fillBaseValue(structField, columnMetag)
	meta.extra = strings.Split(columnMetag.Extra, ",")
	return &meta
}
